﻿/*
 * Created by SharpDevelop.
 * User: Masy Freddy
 * Date: 20/09/2011
 * Time: 12:44
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.AddIn.Hosting;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

using MetaVideoEditorEvolved.AddIn.HostViews;
using MetaVideoEditorEvolved.Engine.Entity;
using MetaVideoEditorEvolved.Helper;

namespace MetaVideoEditorEvolved.Engine
{
	/// <summary>
	/// Description of AddInReaderManager.
	/// </summary>
	public class AddInReaderManager : AddInManager
	{
		private static AddInReaderManager currentInstance;
		private List<KeyValuePair<AddInInformation, ReaderView>> readerAddins = new List<KeyValuePair<AddInInformation, ReaderView>>();
		
		public AddInReaderManager()
		{
			Collection<AddInToken> readerAddIns = AddInStore.FindAddIns(typeof(AddIn.HostViews.ReaderView), addInPath);

			InsertAddIns(readerAddIns, AddInType.Reader);
			
			InitializeAddIn();
		}
		
		public void InitializeAddIn()
		{
			foreach (var addin in AddIns) {
				if(addin.IsEnable)
				{
					if(!(readerAddins.Where((o) => o.Key == addin).Any()))
					{
						ReaderView addInInstance = addin.Token.Activate<ReaderView>(AddInSecurityLevel.FullTrust);
						readerAddins.Add(new KeyValuePair<AddInInformation, ReaderView>(addin, addInInstance));
					}
				}
			}
		}
		
		public static AddInReaderManager Current
		{
			get
			{
				if(currentInstance == null)
				{
					currentInstance = new AddInReaderManager();
				}
				
				return currentInstance;
			}
		}
		
		public Movie ReadMovie(string mediaLocation)
		{
			Movie movie = null;
			
			try
			{
				if (readerAddins==null || readerAddins.Count==0) {
					throw new InvalidOperationException("There is no addin reader available");
				}
				
				foreach (var element in readerAddins) {
					ReaderView addInInstance = element.Value;
					
					var readMovie = addInInstance.ReadMovie(mediaLocation);
					
					if(readMovie != null)
					{
						if(movie == null)
						{
							movie = new Movie();
						}
						
						movie.Backdrops = readMovie.Backdrops != null ? new Collection<Uri>(readMovie.Backdrops) : new Collection<Uri>();
						movie.CastMembers = readMovie.CastMembers != null ? new Collection<CastMember>((from c in readMovie.CastMembers
						                                                                                select new CastMember
						                                                                                {
						                                                                                	Activity = c.Activity,
						                                                                                	FullName = c.FullName,
						                                                                                	Picture = c.Picture,
						                                                                                	Role = c.Role
						                                                                                }).ToList()) : new Collection<CastMember>();
						movie.Duration = readMovie.Duration;
						
						movie.Nationalities = readMovie.Countries != null ? new Collection<string>(readMovie.Countries) : new Collection<string>();
						movie.OriginalTitle = readMovie.OriginalTitle;
						movie.Overview = readMovie.Overview;
						movie.Posters = readMovie.Posters != null ? new Collection<Uri>(readMovie.Posters) : new Collection<Uri>();
						movie.Rating = readMovie.Rating;
						movie.Studios = readMovie.Studios != null ? new Collection<string>(readMovie.Studios) : new Collection<string>();
						movie.Title = readMovie.Title;
						movie.Trailers = readMovie.Trailers != null ? new Collection<Trailer>((from t in readMovie.Trailers
						                                                                       select new Trailer
						                                                                       {
						                                                                       	DefaultPath = t.DefaultPath,
						                                                                       	HighQuality = t.HighQuality,
						                                                                       	LowQuality = t.LowQuality,
						                                                                       	MediumQuality = t.MediumQuality,
						                                                                       	Language = (Language) Enum.Parse(typeof(Language), t.Language.ToString())
						                                                                       }).ToList()) : new Collection<Trailer>();
						movie.Year = readMovie.Year;
					}
				}
			}
			catch(Exception ex)
			{
				if(movie == null)
				{
					movie = new Movie();
				}
				
				movie.Title = mediaLocation;
				movie.OriginalTitle = mediaLocation;
				movie.IsInError = true;
				Tracer.TracerInstance.TraceError(string.Format("Error reading movie {0}",mediaLocation), ex);
			}
			
			return movie;
		}
		
		public Serie ReadSerie(string mediaLocation)
		{
			Serie serie = null;
			
			try
			{
				if (readerAddins==null || readerAddins.Count==0) {
					throw new InvalidOperationException("There is no addin reader available");
				}
				
				foreach (var element in readerAddins) {
					ReaderView addInInstance = element.Value;
					
					var readSerie = addInInstance.ReadSerie(mediaLocation);
					
					if(readSerie != null)
					{
						if(serie == null)
						{
							serie = new Serie();
						}
						
						serie.Backdrops = readSerie.Backdrops != null ? new Collection<Uri>(readSerie.Backdrops) : new Collection<Uri>();
						serie.CastMembers = readSerie.CastMembers != null ? new Collection<CastMember>((from c in readSerie.CastMembers
						                                                                                select  new CastMember
						                                                                                {
						                                                                                	Activity = c.Activity,
						                                                                                	FullName = c.FullName,
						                                                                                	Picture = c.Picture,
						                                                                                	Role = c.Role
						                                                                                }).ToList()) : new Collection<CastMember>();
						serie.Duration = readSerie.Duration;
						serie.Genres = readSerie.Genres != null ? new Collection<string>(readSerie.Genres) : new Collection<string>();
						serie.Graphicals = readSerie.Graphicals != null ? new Collection<Uri>(readSerie.Graphicals) : new Collection<Uri>();
						serie.Name = readSerie.Name;
						serie.Overview = readSerie.Overview;
						serie.Posters = readSerie.Posters != null ? new Collection<Uri>(readSerie.Posters) :  new Collection<Uri>();
						serie.Rating = readSerie.Rating;
						serie.Studios = readSerie.Studios != null ? new Collection<string>(readSerie.Studios) : new Collection<string>();
						serie.Year = readSerie.Year;
						serie.Id = readSerie.Id;
					}
				}
			}
			catch(Exception ex)
			{
				if(serie == null)
				{
					serie = new Serie();
				}

				serie.Name = mediaLocation;
				serie.IsInError = true;
				Tracer.TracerInstance.TraceError(string.Format("Error reading serie {0}",mediaLocation), ex);
			}
			
			return serie;
		}
		
		public Season ReadSeason(string mediaLocation)
		{
			Season season = null;
			
			try
			{
				if (readerAddins==null || readerAddins.Count==0) {
					throw new InvalidOperationException("There is no addin reader available");
				}
				
				foreach (var element in readerAddins) {
					ReaderView addInInstance = element.Value;
					
					var readSeason = addInInstance.ReadSeason(mediaLocation);
					
					if(readSeason != null)
					{
						if(season == null)
						{
							season = new Season();
						}
						
						season.Images = readSeason.Images != null ? new Collection<Uri>(readSeason.Images) : new Collection<Uri>();
						season.Number = readSeason.Number;
					}
				}
			}
			catch(Exception ex)
			{
				if(season == null)
				{
					season = new Season();
				}

				season.Number = 99;
				season.IsInError = true;
				Tracer.TracerInstance.TraceError(string.Format("Error reading season {0}",mediaLocation), ex);
			}
			
			return season;
		}
		
		public Episode ReadEpisode(string mediaLocation)
		{
			Episode episode = null;
			
			try
			{
				if (readerAddins==null || readerAddins.Count==0) {
					throw new InvalidOperationException("There is no addin reader available");
				}
				
				foreach (var element in readerAddins) {
					ReaderView addInInstance = element.Value;
					
					var readEpisode = addInInstance.ReadEpisode(mediaLocation);
					
					if(readEpisode != null)
					{
						if(episode ==null)
						{
							episode = new Episode();
						}
						
						episode.Directors = readEpisode.Directors != null ? new Collection<string>(readEpisode.Directors) : new Collection<string>();
						episode.GuestStars = readEpisode.GuestStars != null ? new Collection<string>(readEpisode.GuestStars) : new Collection<string>();
						episode.Images = readEpisode.Images != null ? new Collection<Uri>(readEpisode.Images) : new Collection<Uri>();
						episode.Name = readEpisode.Name;
						episode.Number = readEpisode.Number;
						episode.Overview = readEpisode.Overview;
						episode.Rating = readEpisode.Rating;
						episode.SeasonNumber = readEpisode.SeasonNumber;
						episode.Writers = readEpisode.Writers != null ? new Collection<string>(readEpisode.Writers) : new Collection<string>();
						episode.Year = readEpisode.Year;
						episode.FirstAired = readEpisode.FirstAired;
					}
				}
			}
			catch(Exception ex)
			{
				if(episode == null)
				{
					episode = new Episode();
				}
				
				episode.Name = mediaLocation;
				episode.IsInError = true;
				Tracer.TracerInstance.TraceError(string.Format("Error reading episode {0}",mediaLocation), ex);
			}
			
			return episode;
		}
		
		public void ShowOption(AddInInformation addInInformation)
		{
			AddInProcess addInProcess = new AddInProcess();
			addInProcess.Start();

			ReaderView addInInstance =  addInInformation.Token.Activate<ReaderView>(addInProcess, AddInSecurityLevel.FullTrust);
			
			addInInstance.ShowOption();
			
			addInProcess.Shutdown();
		}
		
		public bool HasOption(AddInInformation addInInformation)
		{
			var addin = readerAddins.Where((o) => o.Key == addInInformation);
			
			ReaderView addInInstance = null;
			
			if(addin.Any())
			{
				addInInstance = addin.First().Value;
			}
			else
			{
				addInInstance = addInInformation.Token.Activate<ReaderView>(AddInSecurityLevel.FullTrust);
			}
			
			return addInInstance.HasOption();
		}
		
		public override void SaveAllConfiguration()
		{
			base.SaveAllConfiguration();
			
			readerAddins = new List<KeyValuePair<AddInInformation, ReaderView>>();
			
			InitializeAddIn();
		}
	}
}
